/***************************************************
> Copyright (C) 2024 ==LX== All rights reserved.
> File Name: main.c
> Author: lx
> Mail:2998218073@qq.com 
> Created Time: 2024年12月05日 星期四 11时33分58秒
***************************************************/

#include "UserServer.h"
extern int server_socket;
int epfd;
int main(int argc, const char* argv[])
{
	db_init();  //数据连接成功的判断
	signal(SIGINT, handle_signal);
	//创建套接字,监听套接字
	server_socket = socket(AF_INET, SOCK_STREAM, 0);

	if (argc != 3)
	{
		printf("cmd ip port\n");
		return -1;
	}
	//bind 本机ip port
	struct sockaddr_in saddr;
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(atoi(argv[2]));   //port 
	saddr.sin_addr.s_addr = inet_addr(argv[1]);   //ip

	int optval = 1;
	//bind 的地址允许重复使用
	setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
	int isbind = bind(server_socket, (struct sockaddr*)&saddr, sizeof(saddr));
	if (isbind == -1)
	{
		perror("bind");
		return -1;
	}

	//启动监听
	int islisten = listen(server_socket, 10);
	if (islisten == -1)
	{
		perror("listen");
		return -1;
	}
	printf("监听已启动\n");

	// 创建线程池，例如创建10个线程，任务队列容量为100
	ThreadPool* pool = thread_pool_init(10, 100);
	if (pool == NULL) 
	{
		return -1;
	}

	int epfd = epoll_create(1);
	struct epoll_event ev;
	ev.events = EPOLLIN;
	ev.data.fd = server_socket;

	int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, server_socket, &ev);
	if (ret == -1)
	{
		perror("epoll_ctl");
		return -1;
	}
	struct sockaddr_in caddr;
	socklen_t addrlen = sizeof(caddr);
	//char buf[6] = { 0 };
	struct epoll_event events[40];
	while (1)
	{
		int num = epoll_wait(epfd, events, 40, 5000);
		if (num == -1)
		{
			if (errno == EINTR)
			{
				continue;
			}
			else
			{
				perror("epoll_wait");
				break;
			}
		}
		else if (num == 0)
		{
			// 超时无事件发生，继续等待下一次
			continue;
		}
		for (int i = 0; i < num; i++)
		{
			int client_socket;
			int fd = events[i].data.fd;
			if (fd == server_socket)
			{
				client_socket = accept(server_socket, (struct sockaddr*)&caddr, &addrlen);
				printf("ip:%s,port:%d\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
				ev.events = EPOLLIN | EPOLLET;
				ev.data.fd = client_socket;
				epoll_ctl(epfd, EPOLL_CTL_ADD, client_socket, &ev);
			}
			// 将处理客户端的任务添加到线程池任务队列
			if (thread_pool_add_task(pool, client_socket, NULL) == -1) {
				printf("任务队列已满，无法添加客户端任务，关闭客户端连接\n");
				close(client_socket);
				continue;
			}
		}
	}
	close(server_socket);

	return 0;
}
